#include "FontLib.h"
#include "OCR.h"
#include "Debug.h"
#include "ConfigFile.h"
#include "Config.h"

#include <sstream>
#include <fstream>

using namespace std;

FontLib::~FontLib() {
    int size = m_charArray.size();

    for (int i = 0; i < size; i++) {
        delete m_charArray.at(i);
    }
}

Char* Char::parseLibFile(FILE* file) {
    Char *c = new Char;
    uchar *data = c->m_imageData;

    memset(data, BG, s_CHAR_SIZE * s_CHAR_SIZE * sizeof (uchar));

    int size = fread(&c->m_value, sizeof(ushort), 1, file);
    assert(size > 0);

    int count = s_CHAR_SIZE * s_CHAR_SIZE / 8;    // a byte contains 8 bits
    uchar temp;
    for (int i = 0; i < count; i++) {
        size = fread(&temp, sizeof (uchar), 1, file);

        if (temp != 0x00) {
            int s = 0x80;

            for (int j = 0; j < 8; j++, s = s >> 1) {
                if ((temp & s) != 0) {
                    *(data + 8 * i + j) = CHAR;
                }
            }
        }
    }

    return c;
}

void Char::storeData(FILE* file) {
    fwrite(&m_value, sizeof(ushort), 1, file);

    int offset = 0, count = s_CHAR_SIZE * s_CHAR_SIZE / 8;
    char temp;

    for (int i = 0; i < count; i++) {
        temp = 0;

        for (int j = 0; j < 8; j++, offset++) {
            temp = temp << 1;

            if (*(m_imageData + offset) == CHAR) {
                temp |= 1;
            }
        }

        fwrite(&temp, sizeof (char), 1, file);
    }
}

void FontLib::genCurrFontLib() {
    string dataDir = Config::getInstance().getString("path.dir.data");
    
    string lpath = dataDir + "/curr/library";
    wifstream fin(lpath.c_str());
    assert(fin);

    wstring lib;
    fin >> lib;
    fin.close();

    int len = lib.length();
    ushort *subset = new ushort[len];
    for(int i = 0; i < len; i++) {
        subset[i] = (ushort)lib[i];
    }

    string mpath = dataDir + "/max/heiti_64";
    string cpath = dataDir + "/curr/heiti_64";
    FILE *mfile = fopen(mpath.c_str(), "rb");
    assert(mfile);
    FILE *cfile = fopen(cpath.c_str(), "wb");
    buildSubset(mfile, cfile, subset, len);
    fclose(mfile);
    fclose(cfile);

    delete[] subset;
}

void FontLib::buildSubset(FILE *mfile, FILE *cfile, ushort *subset, int len) {
    FontLib *maxLib = parseLibFile(mfile);
    FontLib subLib;

    int offset = 0;
    int size = maxLib->size();
    for (int i = 0; offset < len && i < size; i++) {
        if (subset[offset] == maxLib->at(i)->getValue()) {
            subLib.push_back(new Char(*maxLib->at(i)));

            ++offset;
        }
    }

    subLib.storeData(cfile);
    
    delete maxLib;
}

FontLib* FontLib::parseLibFile(FILE* file) {
    FontLib *fontLib = new FontLib;

    int typeface, size;

    // read the typeface of the lib file
    //fread(&typeface, sizeof(int), 1, file);

    int temp = fread(&size, sizeof (int), 1, file);

    for (int i = 0; i < size; i++) {
        fontLib->push_back(Char::parseLibFile(file));
    }

    return fontLib;
}

void FontLib::storeData(FILE *file) {
    assert(file != NULL);

    int size = m_charArray.size();
    fwrite(&size, sizeof (int), 1, file);

    for (int i = 0; i < size; i++) {
        m_charArray.at(i)->storeData(file);
    }
}
